主張:Agent 本質上是黑盒子——看不到一次請求中間經過幾次推理、幾次工具呼叫、狀態怎麼變化,除錯就只能靠猜。
讀完能做到:認得跑 ADK agent 的四種方式,能用adk run把一次對話存檔、續聊、重播,並用 Web UI 或 Visual Builder 追蹤一次完整執行過程的來龍去脈。
Day 2、3 你已經能寫出一個能動的 agent,但「能動」跟「你知道它為什麼會這樣動」是兩回事。Agent 本質上是黑盒子——一次使用者輸入進去,中間經過幾次模型推理、幾次工具呼叫、狀態怎麼變化,如果你看不到這個過程,除錯就只能靠猜。ADK 花了不少力氣在開發時期的可視化與互動介面上,這正是它相對於自己拼湊 SDK 呼叫最直接的價值之一——今天要把這套工具箱盤點清楚。

官方文件列出跑 ADK agent 的四種方式,前三種是你在開發階段會天天用到的:
| 方式 | 指令 | 用途 |
|---|---|---|
| Dev UI | adk web |
瀏覽器介面,互動對話 + 檢視執行細節 |
| 命令列 | adk run |
終端機內直接對話,適合快速測試與自動化腳本 |
| API Server | adk api_server |
把 agent 開成 RESTful API 服務,供其他程式呼叫 |
| Ambient Agents | — | 事件驅動、無人值守的常駐 agent,這個系列 Day 24 深入 |
今天集中在前三種——它們涵蓋了從「我自己測試」到「跟別的系統整合」的完整光譜。
adk web 起的不只是一個聊天視窗。它會把整個執行過程攤開,主要有三塊:
這三樣東西,剛好對應這個系列後面會深入的三個主題:event 串流是 Day 12「事件驅動架構」的核心,state 變化是 Day 9「Session 管理」與 Day 14「資料流」要處理的東西,trace 視圖則是 Day 29「系統觀測力」的雛形。今天先建立「這些東西存在、而且看得見」的直覺就夠了。
adk run 看起來只是一個終端機聊天介面,但它有一組跟 session 有關的選項,第一次看到很容易被 --save_session、--resume、--replay 這幾個名字搞混。這一節我們照順序把它們跑過一次,你就知道各自吃什麼、什麼時候用。
先講一個最常見的誤會:這三個選項不是串在同一行用的。像下面這樣寫是錯的:
# ❌ 不要這樣寫,這三個選項不會一起出現
adk run --save_session --resume --replay my_agent
它們是三個獨立的步驟,各自吃不同的檔案。往下看。
adk run my_agent
進去之後就是一問一答的互動模式,打 exit 或按 Ctrl+C 離開:
Running agent my_agent, type exit to exit.
[user]: What's the weather in New York?
[my_agent]: The weather in New York is sunny with a temperature of 25°C.
[user]: exit
如果只想丟一句話就走人,把問題當參數接在後面,跑完直接結束,不進互動模式:
adk run path/to/my_agent "hello"
--save_session)加上 --save_session,你退出對話時 ADK 會問你要用什麼 session ID:
adk run --save_session path/to/my_agent
存出來的檔案會放在 path/to/my_agent/<session_id>.session.json——注意它是存在 agent 目錄底下,不是你當下的工作目錄。
不想被問,就用 --session_id 先指定名字:
adk run --save_session --session_id my_session path/to/my_agent
這行跑完會得到 path/to/my_agent/my_session.session.json。
--resume)--resume 吃的就是上一步存出來的那個檔案:
adk run --resume path/to/my_agent/my_session.session.json path/to/my_agent
這行有兩個路徑,第一次看很容易漏掉:前面那個是 session 檔案,後面那個是 agent 目錄,兩個都要給。跑起來之後,ADK 會先把先前的 state 與 event history 印出來,然後你就能接著上次的對話往下講。
所以 Save 與 Resume 是一組:先存檔,之後續聊。
--replay)--replay 是另外一回事,跟前面兩個沒有關係。它吃的不是 --save_session 存出來的檔案,而是一份你自己手寫的 input JSON:
adk run --replay path/to/input.json path/to/my_agent
那個 input.json 長這樣,只有兩個欄位——初始 state,加上一串要依序問的問題:
{
"state": {"key": "value"},
"queries": ["What is 2 + 2?", "What is the capital of France?"]
}
跑下去就非互動地一路問完,你完全不用打字。這對做 demo、寫教學、跑迴歸測試特別好用——把一段「已知會出錯」的互動寫成 queries 清單,之後隨時重跑,不必每次手動重打一模一樣的對話。
一句話記住三者的差別:
| 選項 | 吃什麼檔案 | 什麼時候用 |
|---|---|---|
--save_session |
不吃,是產生檔案 | 想把這次對話留下來 |
--resume |
上面存出來的 .session.json |
想接著上次的 state 繼續聊 |
--replay |
你自己手寫的 input JSON | 想不打字自動跑完一串問句 |
同一個 adk run 還有幾個開發時很常按到的旗標,先知道有這些東西,需要時回來查:
| 選項 | 作用 |
|---|---|
--state |
用 JSON 字串直接給這次執行的初始 state |
--timeout |
單輪的逾時,例如 30s、5m |
--in_memory |
這次跑完不留任何 session 資料 |
--jsonl |
輸出結構化 JSONL,方便給腳本解析 |
--session_service_uri |
換掉預設的 session 儲存位置 |
--default_llm_model |
agent 沒指定模型時用的預設模型 |
預設的 session 存在 <agents_dir>/<agent>/.adk/session.db(每個 agent 一個 SQLite),artifact 存在 <agents_dir>/<agent>/.adk/artifacts。想換成別的地方就給 URI,例如:
adk run --session_service_uri "sqlite:///my_sessions.db" path/to/my_agent
第一,這些選項只有 Python CLI 有。--save_session、--resume、--replay、--session_id、--session_service_uri、--artifact_service_uri 都是 Python 專屬。Go 的 console launcher 不吃這些旗標,要做 session 持久化得在程式碼裡給 launcher.Config 一個持久的 session.Service(例如 session/database)。
第二,遙測預設是關的。ADK CLI 會收集匿名使用量資料,但要你自己跑 adk telemetry enable 才開始送,隨時可以 adk telemetry status 查狀態、adk telemetry disable 關掉。偏好存在 ~/.adk/config.json。
最後補一個小技巧:adk run 支援用 stdin pipe 注入第一句 prompt,寫自動化腳本或快速煙霧測試時很方便:
echo "Please start by listing files" | adk run file_listing_agent
當你的 agent 需要被其他前端、其他服務呼叫,而不是只能在終端機或瀏覽器裡互動,adk api_server 把它包成一組 REST 端點:
/list-apps,列出目前有哪些可用的 agent啟動之後有互動式的 API 文件可以直接測試每個端點——這對前端團隊要串接你的 agent 時特別有用,他們不需要先讀懂你的 Python 程式碼,對著 API 文件就能開始接。
如果連 Python 都不想寫,ADK Web 介面裡有一個 Visual Builder(Python v1.18.0,標記 Experimental),提供拖拉式的視覺化設計環境,而且內建一個 AI 助理可以直接用自然語言請它幫你改 agent。
開啟方式很簡單:跑 adk web,在介面左上角點選 +(新增)符號就能開始建立。編輯畫面分成三個區塊:左側面板編輯元件的屬性、中央面板新增元件、右側面板則是那個 AI 助理,可以直接用一句話請它幫忙,官方文件給的示範 prompt 是:
Help me add a dice roll tool to my current agent.
Use the default model if you need to configure that.
Visual Builder 支援的元件涵蓋了 ADK 常用的建構積木:Agents(Root Agent、LLM Agent、Sequential Agent、Loop Agent、Parallel Agent)、Tools(部分預建工具與自訂工具)、以及 Callbacks。這些名詞在接下來的 Day 6(工具)與 Day 12(callback)會逐一展開,現在先知道它們在 Visual Builder 裡都能透過拖拉建立。
一個關鍵事實:Visual Builder 底層產出的其實就是 Day 3 提過的 Agent Config 格式——.yaml 檔加上 Python 寫的自訂工具程式碼。以一個 DiceAgent 專案為例,產出結構長這樣:
DiceAgent/
root_agent.yaml # main agent code
sub_agent_1.yaml # sub agents (if any)
tools/ # tools directory
__init__.py
dice_tool.py # tool code
這些檔案會被寫進你執行 adk web 那個目錄底下的一個新子資料夾。這代表兩件事:第一,你要在一個有寫入權限的開發目錄下執行這個指令,不要在系統層級或唯讀的目錄下跑;第二,產出的檔案你完全可以拿到一般開發環境裡用文字編輯器繼續改——但官方文件也提醒,某些用手動編輯做的變更之後可能跟 Visual Builder 不相容。
因為底層是 Agent Config 格式,Visual Builder 繼承了 Day 3 講過的所有限制:目前只支援 Gemini 模型,且一些進階功能(不在「支援的元件」清單裡的東西)無法透過它建構。除此之外還有幾個操作上的細節:
adk web 服務期間開放——這代表 Visual Builder 是純粹的開發期工具,在 headless(無圖形介面)或已經部署的環境裡無法使用它來改 agent。再次強調 Day 2 提過的那句話:ADK Web(包含 Visual Builder)只能用在開發階段,絕對不要把它當成生產環境的管理介面。
到這裡,你手上已經有完整的「開發時期武器庫」:命令列快速測試(而且知道怎麼存檔、續聊、重播),Web UI 看穿執行細節,API Server 讓 agent 變成服務,Visual Builder 讓不寫程式碼的人也能參與建構。這四樣工具會貫穿接下來整個系列——每次你加了新工具、新的 workflow、新的安全機制,回到 Dev UI 觀察執行細節,永遠是驗證「這個東西真的照我想的方式運作」最快的方法。
明天,我們要換一個方向:不是你在 UI 裡操作,而是讓 AI coding agent 反過來幫你寫 ADK 程式碼。
Google ADK 官方網站
GitHub - Agent Development Kit (ADK) 2.0